<?php
/*
*
*
*/

namespace hpnWse\nSpu {

use \hpnWse\stStrUtil;
use \hpnWse\stObjUtil;
use \hpnWse\stAryUtil;

/// 文件上传
class stFileUpld extends \hpnWse\stSpu
{
	/// 运行
	/// $a_Prms
	/// {
	/// c_DstDiry: String，目的目录，文件将被转移至这里
	/// c_SrcData: String$Array，Base64编码的字符串，或$_FILES的元素
	/// c_FileExtn: String，文件扩展名，默认自动推导
	/// c_IvldExtns: String[]，无效扩展名，默认['php', ...]（包含常见脚本文件格式）
	/// c_VldExtns: String[]，有效扩展名，默认null表示不使用，否则提供有效扩展名数组（小写形式）
	/// c_RqrImgExtn: Boolean，扩展名必须是图像，若true则自动设置c_VldExtns（仅当其为null）
	/// c_CastExtn: String，转换扩展名，默认null，若非空则当扩展名无效时转成该值而不返回错误响应
	/// c_MaxSize: int，最大字节数，默认0表示不限制
	/// }
	/// 返回：
	/// {
	/// c_ErrHsc: Number，错误Http状况码
	/// c_ErrCode: Number，错误码，0表示成功
	/// c_ErrMsg: String，错误信息，null表示成功
	/// c_Flnm：String，文件名（含扩展名），32个字符（MD5）＋“.[扩展名]”
	/// c_Extn: String，扩展名，一定是小写，不带“.”
	/// }
	public static function cRun($a_Prms)
	{
		$l_SrcData = &$a_Prms['c_SrcData'];
		$l_IsBase64 = is_string($l_SrcData);
		$l_Extn = stObjUtil::cFchPpty($a_Prms, 'c_FileExtn');
		$l_MaxSize = stObjUtil::cFchIntPpty($a_Prms, 'c_MaxSize');

		if ($l_IsBase64) // Base64
		{
			// 数据形如
			// 
			//                       ↑ 解码从这里开始（逗号后）

			if (!$l_Extn)
			{
			//	if (0 != preg_match('/\\/([^;]+);/', $l_SrcData, $l_Extn))
			//	{ $l_Extn = $l_Extn[1]; }

				$l_Bgn = stStrUtil::cFind($l_SrcData, '/');
				$l_End = stStrUtil::cFind($l_SrcData, ';', $l_Bgn + 1);
				$l_Extn = stStrUtil::cSub($l_SrcData, $l_Bgn + 1, $l_End);
			}

			$l_CmaIdx = stStrUtil::cFind($l_SrcData, ',');
			$l_DcdData = stStrUtil::cSub($l_SrcData, $l_CmaIdx + 1);
			$l_FileData = base64_decode($l_DcdData);
			if (!$l_FileData)
			{ return array('c_ErrHsc' => 400, 'c_ErrCode' => -2, 'c_ErrMsg' => 'Base64编码错误'); }

			if (($l_MaxSize > 0) && (strlen($l_FileData) > $l_MaxSize))
			{ return array('c_ErrHsc' => 400, 'c_ErrCode' => -2, 'c_ErrMsg' => '文件过大'); }
		}
		else // $_Files
		{
			if (0 !== $l_SrcData['error'])
			{ return array('c_ErrHsc' => 500, 'c_ErrCode' => -1, 'c_ErrMsg' => '上传失败'); }

			if (($l_MaxSize > 0) && ($l_SrcData['size'] > $l_MaxSize))
			{ return array('c_ErrHsc' => 400, 'c_ErrCode' => -2, 'c_ErrMsg' => '文件过大'); }

			if (!$l_Extn)
			{
				$l_Extn = stStrUtil::cGetFileExtn($l_SrcData['name']);
			}
		}

		$l_Extn = strtolower($l_Extn);
		$l_Ivlds = stObjUtil::cFchPpty($a_Prms, 'c_IvldExtns', 
			array('php', 'phtml', 'asp', 'aspx', 'ascx', 'jsp', 'cfm', 'cfc', 'pl', 'bat', 'exe', 'dll', 'reg', 'cgi'));
		$l_Vlds = stObjUtil::cFchPpty($a_Prms, 'c_VldExtns', null);
		if ((null === $l_Vlds) && stObjUtil::cFchBoolPpty($a_Prms, 'c_RqrImgExtn', false))
		{ $l_Vlds = array('bmp', 'png', 'jpg', 'jpeg', 'gif', 'tif', 'tiff', 'webp'); }
		$l_CastExtn = stObjUtil::cFchPpty($a_Prms, 'c_CastExtn', null);

		if ((stAryUtil::cIdxOf($l_Ivlds, $l_Extn) >= 0) ||
			((null !== $l_Vlds) && (stAryUtil::cIdxOf($l_Vlds, $l_Extn) < 0)))
		{
			if (null === $l_CastExtn)
			{ return array('c_ErrHsc' => 400, 'c_ErrCode' => -2, 'c_ErrMsg' => '无效文件'); }

			$l_Extn = $l_CastExtn;
		}
		
		$l_Flnm = md5(uniqid(mt_rand(), true));
		if (\hpnWse\fBool($l_Extn))
		{
			$l_Flnm .= '.';
			$l_Flnm .= $l_Extn;
		}
		$l_Path = stStrUtil::cEnsrDiry($a_Prms['c_DstDiry']) . $l_Flnm;
		
		if ($l_IsBase64)
		{
			file_put_contents($l_Path, $l_FileData);
		}
		else
		{
			if (! move_uploaded_file($l_SrcData['tmp_name'], $l_Path))
			{ return array('c_ErrHsc' => 500, 'c_ErrCode' => -1, 'c_ErrMsg' => '转储失败'); }
		}

		return array('c_ErrHsc' => 200, 'c_ErrCode' => 0, 'c_ErrMsg' => null, 'c_Flnm' => $l_Flnm, 'c_Extn' => $l_Extn);
	}
}

} // namespace hpnWse\nSpu

//////////////////////////////////// OVER ////////////////////////////////////